<script setup lang="ts">
import { unwrapApiBody, type ApiResponse } from '../../../utils/http/factory'
import { buildPublicCanonicalUrl } from '../../../utils/public-canonical-url'
import { safeExternalHref } from '../../../utils/safe-external-href'

definePageMeta({
  layout: 'public',
})

const route = useRoute()
const router = useRouter()
const runtimeConfig = useRuntimeConfig()
const slug = computed(() => route.params.publicSlug as string)

function parsePage(raw: unknown): number {
  const n =
    typeof raw === 'string'
      ? Number.parseInt(raw, 10)
      : typeof raw === 'number'
        ? raw
        : Number.NaN
  if (!Number.isFinite(n) || n < 1) {
    return 1
  }
  return Math.floor(n)
}

const page = ref(parsePage(route.query.page))

watch(
  () => [route.params.publicSlug, route.query.page] as const,
  () => {
    page.value = parsePage(route.query.page)
  },
)

type PublicRssListItem = { title?: string | null; canonicalUrl?: string | null; canonical_url?: string | null }

type Payload = {
  items: PublicRssListItem[]
  total: number
  page: number
  pageSize: number
}

function rssPublicHref(it: PublicRssListItem): string | undefined {
  const u = it.canonicalUrl ?? it.canonical_url
  return safeExternalHref(u)
}

function rssPublicTitle(it: PublicRssListItem): string {
  const t = it.title
  return typeof t === 'string' && t.trim().length ? t : '未命名'
}

function rssHostname(href: string | undefined): string {
  if (!href) {
    return ''
  }
  try {
    return new URL(href).hostname
  }
  catch {
    return href
  }
}

function onPageChange(p: number) {
  page.value = p
  const query: Record<string, string | string[] | undefined> = { ...route.query }
  if (p > 1) {
    query.page = String(p)
  }
  else {
    delete query.page
  }
  void router.replace({ query })
}

const { data, pending, error } = await useAsyncData(
  () => `public-reading-${slug.value}-${page.value}`,
  async () => {
    const base = `/api/public/profile/${encodeURIComponent(slug.value)}/reading`
    const url = page.value > 1 ? `${base}?page=${page.value}` : base
    const res = await $fetch<ApiResponse<Payload>>(url)
    return unwrapApiBody(res)
  },
  { watch: [slug, page] },
)

const readingItems = computed(() =>
  (data.value?.items ?? []).map(item => ({
    item,
    href: rssPublicHref(item),
  })),
)

const canonicalUrl = computed(() =>
  buildPublicCanonicalUrl(runtimeConfig.public.siteUrl, route.fullPath),
)

useHead(() => ({
  link: canonicalUrl.value
    ? [{ rel: 'canonical', href: canonicalUrl.value }]
    : [],
}))

usePageTitle(() => {
  const parts: string[] = []
  if (page.value > 1) {
    parts.push(`第 ${page.value} 页`)
  }
  parts.push('阅读', `@${slug.value}`)
  return parts
})
</script>

<template>
  <UContainer class="py-8 lg:py-10 max-w-6xl">
    <div v-if="pending && !data" class="text-muted py-10">
      加载中…
    </div>
    <UAlert
      v-else-if="error && !data"
      color="error"
      title="无法加载阅读列表"
      class="my-6"
    />
    <template v-else-if="data">
      <UEmpty
        v-if="data.total === 0"
        title="暂无阅读摘录"
        description="站主尚未同步任何公开阅读条目。"
      />
      <template v-else>
        <h2 class="text-xs font-semibold uppercase tracking-wider text-muted mb-4">
          阅读
        </h2>
        <ul class="border-t border-default">
          <li
            v-for="({ item, href }, i) in readingItems"
            :key="i"
            class="border-b border-default last:border-b-0"
          >
            <a
              v-if="href"
              :href="href"
              target="_blank"
              rel="noopener noreferrer"
              class="group block py-5 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary rounded-lg"
            >
              <div class="text-base font-semibold text-pretty text-primary group-hover:underline">
                {{ rssPublicTitle(item) }}
              </div>
              <div class="mt-1.5 break-all text-sm text-muted">
                {{ rssHostname(href) }}
              </div>
            </a>
            <div v-else class="py-5 text-muted">
              {{ rssPublicTitle(item) }}
            </div>
          </li>
        </ul>
        <div v-if="data.total > 10" class="flex justify-end mt-6">
          <UPagination
            :page="page"
            :total="data.total"
            items-per-page="10"
            size="sm"
            @update:page="onPageChange"
          />
        </div>
      </template>
    </template>
  </UContainer>
</template>
